<?php
namespace haibao\cms\sengine;

use \haibao\frame\data\query\Condition;

class ImageSphinxDb extends Base {
	/**
	 * 加权值
	 */
	const  WEIGHING = 1000;
	
	/**
	 * 加权步长
	 * @var int
	 */
	const WEIGHING_STEP = 100;
	
	/**
	 * 时段--天
	 * @var int
	 */
	const DAY_STEP = 365;
	/**
	 * 索引返回的最大记录数
	 * @var int
	 */
	const MAXMATCHES = 1000;
	
	private $indexName = 'WebSearchImage';
	
	public function __construct(){
		parent::__construct();
		$this->setConfig( \haibao\classlibrary\cms\Config::CLASSLIBRARY_CONFIG_SPHINX_IMAGE );
		$this->setMatchMode(SPH_MATCH_EXTENDED2);
		$this->setFieldWeights(array('Tags'=>20,'Description'=>5,'Content'=>1));
	}
	
	/**
	 * @param \haibao\cms\model\filter\ImageSphinxDb $filter
	 */
	public function search($filter){
		$ids = array();
		//where
		$query = $this->processConditions($filter);
		//order
		$this->setOrder($filter);
		//limit
		$pager = $filter->getPager();
		
		if ($pager){
			$this->setLimits ( ($pager->getCurrentPage() - 1)*$pager->getPageSize() , $pager->getPageSize() , self::MAXMATCHES);
		} else if ($limits = $filter->getLimit()) {
			$this->setLimits($limits[0],$limits[1],self::MAXMATCHES);
		} else {
			$this->setLimits(0,20, self::MAXMATCHES);
		}
		
		$result = $this->query($query, $this->indexName);
		
		return $result;
	}
	
	public function searchAll($filterArr){
		$data = null;
		if ($filterArr){
			foreach ($filterArr as $filter){
				$this->resetFilters();
				$this->resetGroupBy();
				$pager = $filter->getPager();
				$offset = ($pager->getCurrentPage() - 1)*$pager->getPageSize();
				$limit = $pager->getPageSize();
				$this->setLimits($offset, $limit);
				$query = $this->processConditions($filter);
				$this->addQuery($query, $this->indexName);
			}
			
			$data = $this->runQueries();
		}
		
		return $data;
	}
	
	public function highLight($contentArr,$keyword,$options = array()){
		if ($contentArr){
			$_options = array(
					'before_match'=>'<b>',
					'after_match'=>'</b>',
					'chunk_separator'=>'...',
					'limit'=>150,
					'around'=>10,
					'allow_empty'=>true,
					'html_strip_mode'=>'index',
			);
			$_options = array_merge($_options,$options);
			$contentArr = $this->buildExcerpts($contentArr, $this->indexName, $keyword,$_options);
		}
		
		return $contentArr;
	}
	
	private function setOrder($filter){
		$orderType = SPH_SORT_RELEVANCE;
		$strOrder = '';
		$orders = $filter->getOrders();
		
		if ($orders){
			foreach ($orders as $orderArr){
				$keyName = $this->getFieldName($orderArr[0]);
				if ($keyName == \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_HEAT){
					$strOrder = '@weight/POW(('.time().'-IndexTime),0.3)';
					$orderType = SPH_SORT_EXPR;
				} else {
					$strOrder = $keyName;
					$orderType = SPH_SORT_ATTR_DESC;
				}
				
			}
			
			if ($strOrder){
				$this->setSortMode($orderType,$strOrder);
			}
		}
		
		if (!$strOrder){
			$this->setSortMode(SPH_SORT_RELEVANCE);
		}
	}
	
	private function processConditions($filter){
		$query = '';
		$conditions = $filter->getConditions();
		
		foreach ($conditions as $condition){
			$keyName = $condition->getKeyName();
			$type = $condition->getConditionType();
			$value = $condition->getConditionValue();
			switch ($condition->getKeyName()){
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_TAG_PRIMARY:
					$query .= '(@Tags "haibaopound'.$this->getWordQuery($value).'haibaopound") | @(Content,Description) "'.$this->getWordQuery($value).'"';
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CONTENTS_FULL:
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$query .= ' @(Tags,Content,Description) "'.$this->getWordQuery($value).'"';
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$query .= ' @(Tags,Content,Description) -("'.$this->getWordQuery($value).'")';
					}
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CONTENTS:
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$query .= ' @(Tags,Content,Description) '.$this->getWordQuery($value);
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$query .= ' @(Tags,Content,Description) -('.$this->getWordQuery($value).')';
					}
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CONTENT:
					//全文本字段
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$query .= ' @Content '.$this->getWordQuery($value);
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$query .= ' @Content -('.$this->getWordQuery($value).')';
					}
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_TAGS:
					//全文本字段
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$query .= ' @Tags '.$this->getWordQuery($value);
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$query .= ' @Tags -('.$this->getWordQuery($value).')';
					}
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CONTENT_FULL:
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$query .= ' @Content "'.$this->getWordQuery($value).'"';
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$query .= ' @Content -("'.$this->getWordQuery($value).'")';
					}
					break;
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CREATE_TIME:
				case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_INDEX_TIME:
					$this->setTimeQuery($keyName,$value,$type);
					break;
				case \haibao\cms\model\filter\SphinxDb::CONDITION_FIELD_STATUS:
					if (!is_array($value)){
						$value = array($value);
					}
					
					if ($type == Condition::CONDITION_EQUAL || $type == Condition::CONDITION_IN){
						$this->setFilter($this->getFieldName($keyName), $value);
					}
					else if ($type == Condition::CONDITION_NOTEQUAL || $type == Condition::CONDITION_NOTIN){
						$this->setFilter($this->getFieldName($keyName), $value , true);
					}
					break;
			}
		}
		
		return $query;
	}
	
	private function getWordQuery($value){
		$query = '';
		if (!is_array($value)){
			$value = array(' '.$value.' ');
		}
		
		foreach ($value as $word){
			if ($query){
				$query .= '|';
			}
			
			$query .= $this->escapeString($word);
		}
		
		return $query;
	}
	
	//时间都是区间
	private function setTimeQuery($keyName,$value,$type){
		$data = array(0,time());
		if (is_array($value)){
			if ($value[0]){
				$data[0] = (int)$value[0];
			}
			if ($value[1]){
				$data[1] = (int)$value[1];
			}
		}
		
		$this->setFilterRange($this->getFieldName($keyName), $data[0], $data[1]);
	}
	
	private function getFieldName($keyName){
		$fieldName = '';
		switch ($keyName){
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CONTENT:
				$fieldName = 'Content';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_INDEX_TIME:
				$fieldName = 'IndexTime';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_CREATE_TIME:
				$fieldName = 'CreateTime';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_STATUS:
				$fieldName = 'Status';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_DOWN_NUM:
				$fieldName = 'DownNum';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_HEAT:
				$fieldName = 'Heat';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_MARK_NUM:
				$fieldName = 'MarkNum';
				break;
			case \haibao\cms\model\filter\ImageSphinxDb::CONDITION_FIELD_NAME_TAGS:
				$fieldName = 'Tags';
				break;
		}
		
		return $fieldName;
	}
	
	
}